/**
 * 生成占位符UUID
 * @returns {string}
 */
function getPlaceholderUUID() {
  let length = 10
  const characters =
    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
  let result = ''
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * characters.length))
  }
  return '##' + result.toUpperCase() + '##'
}

/**
 * 计算公式
 * @param {{text: string, marks: Array, value: Object}} params
 * @returns
 */
function compileScript(params) {
  const { text, marks = [], value = {} } = params
  if (!text) return new Error('非法代码，不能为空')
  try {
    let str = text
    marks.sort((a, b) => a.from.ch - b.from.ch)
    let lineItemList = []
    // 按照换行符拆分，并初始化每行的偏移量，用于替换变量
    str.split('\n').forEach((line, index) => {
      lineItemList.push({
        lineText: line,
        lineOffset: 0,
      })
    })
    let replaceMarkMap = {}
    for (const mark of marks) {
      const { fieldCode,markType,fieldPath, from, to } = mark
      let { lineText, lineOffset } = lineItemList[from.line]
      if (fieldCode !== undefined) {
        let placeholderId = getPlaceholderUUID()
        if (markType == 'fieldName') {
          // 直接返回字段/变量名称即可
          replaceMarkMap[placeholderId] = 'vm.getFieldName("'+fieldPath+'")'
        }else if (markType == 'fieldValue') {
          // 直接返回字段/变量名称即可
          replaceMarkMap[placeholderId] = 'vm.getFieldValue("'+fieldPath+'")'
        }
        // 替换字符串的指定变量占位符为固定格式字符串
        const startIndex = from.ch + lineOffset
        const endIndex = to.ch + lineOffset
        lineText = lineText.slice(0, startIndex) + placeholderId + lineText.slice(endIndex)
        // 更新偏移量和行占位符
        lineOffset += placeholderId.length - (to.ch - from.ch)
        lineItemList[from.line] = {
          lineText: lineText,
          lineOffset: lineOffset,
        }
      } else {
        console.error(`公式错误：${fieldCode} 值不存在`)
        return undefined
      }
    }
    // 多行拼接为一行字符串
    let script = lineItemList.map((item) => {
      return item.lineText
    }).join('\n')
    // 字符串占位符替换为实际变量值，组装最后的执行脚本
    for (const placeholderId in replaceMarkMap) {
      script = script.replace(new RegExp(placeholderId, 'g'), replaceMarkMap[placeholderId])
    }
    return script
  } catch (e) {
    console.error('脚本生成失败',params, e)
    return ''
  }
}
export { compileScript }
